{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Day08 掌握`^`与`$`的用法"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "　　通过在前面日程里对**正则表达式**的学习，我们目前只剩下`^`、`$`以及`|`这三个**元字符**还没有介绍，按照其功能特点，我们今天接着来介绍`^`（顺便介绍一下`$`）的用法。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "　　`^`有点像`?`，其按照使用方式的差异具有两种截然不同的功能，首先我们来介绍其**匹配字符串开头位置**的功能，我们从实际例子出发，譬如对下面的字符串`s`，我们想匹配连续3个出现的数字很容易："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2020-09-02T13:28:21.112258Z",
     "iopub.status.busy": "2020-09-02T13:28:21.111257Z",
     "iopub.status.idle": "2020-09-02T13:28:21.127181Z",
     "shell.execute_reply": "2020-09-02T13:28:21.127181Z",
     "shell.execute_reply.started": "2020-09-02T13:28:21.112258Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['666', '777', '876', '323']"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import re\n",
    "\n",
    "s = '666 adas777 asdsa 876 323d ——'\n",
    "\n",
    "re.findall('[0-9]{3}', s)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2020-09-02T13:28:21.129174Z",
     "iopub.status.busy": "2020-09-02T13:28:21.129174Z",
     "iopub.status.idle": "2020-09-02T13:28:21.135159Z",
     "shell.execute_reply": "2020-09-02T13:28:21.135159Z",
     "shell.execute_reply.started": "2020-09-02T13:28:21.129174Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['666']"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "re.findall('^[0-9]{3}', s)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "　　可以看到这时返回的结果里只有`666`，因为我们的`^`对**正则表达式**开头的模式限定了必须从原始字符串开头位置进行匹配，所以恰巧满足条件又在原始字符串开头位置的`666`作为唯一结果得以输出。\n",
    " \n",
    "　　类似的还有与**匹配开头位置**功能相反的`$`，其功能是**匹配结尾位置**，对应的要写到整个正则表达式的最后面去："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2020-09-02T13:28:21.137153Z",
     "iopub.status.busy": "2020-09-02T13:28:21.137153Z",
     "iopub.status.idle": "2020-09-02T13:28:21.144134Z",
     "shell.execute_reply": "2020-09-02T13:28:21.143137Z",
     "shell.execute_reply.started": "2020-09-02T13:28:21.137153Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[' CPD']"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s = 'AAA ds 32 das  1221 CPD'\n",
    "\n",
    "# 在结尾位置匹配1个空格+连续3个大写字母的模式\n",
    "re.findall(' [A-Z]{3}$', s)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "　　介绍完上面`^`的第一种功能以及与之相对的`$`的功能之后，下面我们来学习今天的重点也就是`^`的第二种功能——**反选模式集合**，首先来看看下面的例子，对于下面的字符串`s`，假如我们想要匹配到所有不为`e`、`h`、`m`的小写字母："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2020-09-02T13:28:21.146130Z",
     "iopub.status.busy": "2020-09-02T13:28:21.145132Z",
     "iopub.status.idle": "2020-09-02T13:28:21.153111Z",
     "shell.execute_reply": "2020-09-02T13:28:21.152113Z",
     "shell.execute_reply.started": "2020-09-02T13:28:21.146130Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['q', 'w', 'w', 'w', 'q', 'w', 'q']"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s = 'qwewwqhewqm'\n",
    "\n",
    "re.findall('[a-dfgi-ln-z]', s)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "　　可以看到提取到的结果虽然正确，但是挺费事，如果要排除的字符是某些汉字或字符，那就不好处理了，而`^`配合`[]`的功能即为**反选模式集合**，利用它来改造上面的例子："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2020-09-02T13:28:21.154108Z",
     "iopub.status.busy": "2020-09-02T13:28:21.154108Z",
     "iopub.status.idle": "2020-09-02T13:28:21.162086Z",
     "shell.execute_reply": "2020-09-02T13:28:21.161089Z",
     "shell.execute_reply.started": "2020-09-02T13:28:21.154108Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['q', 'w', 'w', 'w', 'q', 'w', 'q']"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "re.findall('[^ehm]', s)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "　　可以看到，只要在`[]`中把`^`置于第一个位置，就可以排除掉`[]`里剩余的其他模式，非常的方便快捷~"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Day08 课后小测验\n",
    "\n",
    "　　相信通过上面的内容，你已经对`^`和`$`的用法有了一定了解，快来操练一番巩固知识：请你从下面的列表中提取检查所有的字符串元素是否在开头位置不为`服`并且结尾位置不为`局`的字符串："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2020-09-02T13:28:21.164082Z",
     "iopub.status.busy": "2020-09-02T13:28:21.163086Z",
     "iopub.status.idle": "2020-09-02T13:28:21.170065Z",
     "shell.execute_reply": "2020-09-02T13:28:21.169067Z",
     "shell.execute_reply.started": "2020-09-02T13:28:21.164082Z"
    }
   },
   "outputs": [],
   "source": [
    "target = ['国税局', '公安局', '派出所', '服务中心', '水利局', '气象局', '监督委员会']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['派出所', '监督委员会']"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "[i for i in target if re.findall('^[^服].+[^局]$',i)!=[]]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2020-08-26T12:55:19.898241Z",
     "iopub.status.busy": "2020-08-26T12:55:19.897245Z",
     "iopub.status.idle": "2020-08-26T12:55:19.904225Z",
     "shell.execute_reply": "2020-08-26T12:55:19.903227Z",
     "shell.execute_reply.started": "2020-08-26T12:55:19.898241Z"
    }
   },
   "source": [
    "　　请将你的答案截图发到本帖评论区~"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.7"
  },
  "widgets": {
   "application/vnd.jupyter.widget-state+json": {
    "state": {},
    "version_major": 2,
    "version_minor": 0
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
